package org.whale.bha.util;

import java.io.IOException;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.xml.bind.JAXB;

import org.apache.http.client.ClientProtocolException;
import org.springframework.util.Assert;
import org.whale.bha.bean.base.BHABaseResponse;
import org.whale.bha.bean.request.BHAAccountInfoRequest;
import org.whale.bha.bean.request.BHACancelAuthorizeAutoRepaymentRequest;
import org.whale.bha.bean.request.BHACancelAuthorizeAutoTransferRequest;
import org.whale.bha.bean.request.BHACompleteTransactionRequest;
import org.whale.bha.bean.request.BHAFreezeRequest;
import org.whale.bha.bean.request.BHAPlatformInfoRequest;
import org.whale.bha.bean.request.BHAProjectQueryRequest;
import org.whale.bha.bean.request.BHAQueryRequest;
import org.whale.bha.bean.request.BHAUnFreezeRequest;
import org.whale.bha.bean.response.BHAAccountInfoResponse;
import org.whale.bha.bean.response.BHACommonResponse;
import org.whale.bha.bean.response.BHACpTransactionRecordResponse;
import org.whale.bha.bean.response.BHAFreezeRecordResponse;
import org.whale.bha.bean.response.BHAProjectQueryResponse;
import org.whale.bha.bean.response.BHARechargeRecordResponse;
import org.whale.bha.bean.response.BHAWithdrawRecordResponse;
import org.whale.bha.bean.type.BHACompleteTransactionModeEnum;
import org.whale.bha.bean.type.BHAQueryModeEnum;
import org.whale.bha.bean.type.BHAServiceNameEnum;

public class RedirectUtil {
	private static SimpleDateFormat sdf =   new SimpleDateFormat( " yyyy-MM-dd HH:mm:ss " );
	
	
	/**
	 * 查询帐户信息
	 * --------------输入参数------------------
	 * service 名称  ACCOUNT_INFO 
	 * platformNo  Y  商户编号
		platformUserNo  Y  平台会员编号
	 * -------------输出参数-------------------
	 * platformNo  Y  商户编号
		code  Y  【见返回码】
		description  N  描述信息
		memberType  Y  【见会员类型】
		activeStatus  Y  【见会员激活状态】
		balance  Y  账户余额
		availableAmount  Y  可用余额
		freezeAmount  Y  冻结金额
		cardNo  N  绑定的卡号,没有则表示没有绑卡
		cardStatus  N  【见绑卡状态】
		bank  N  【见银行代码】
		autoTender  Y  是否已授权自劢投标,true 或则 false
	 */
	public BHAAccountInfoResponse accountInfo(String platformNo,String platformUserNo) throws ClientProtocolException, IOException{
		Assert.hasLength(platformNo, "平台编号不能为空");
		Assert.hasLength(platformUserNo, "平台用户编号不能为空");
		BHAAccountInfoRequest req = new BHAAccountInfoRequest();
		req.setPlatformNo(platformNo);
		req.setPlatformUserNo(platformUserNo);
		return BHAUtil.doBHAService(BHAServiceNameEnum.ACCOUNT_INFO, BHAAccountInfoResponse.class, req);
	}
	
	/**
	 * 转帐确认
	 * service 名称  COMPLETE_TRANSACTION 
	 * --------------输入参数------------------
	 * platformNo  Y  商户编号
		requestNo  Y  请求流水号
		mode  Y  CONFIRM 表示解冻后完成资金划转，CANCEL 表示解冻后取消转账
		notifyUrl  Y  服务器通知 URL
	 *------------输出参数--------------------
	 * platformNo  Y  商户编号
		code  Y  【见返回码】
		description  N  描述信息
	 * -------------回调通知-------------------
	 * platformNo  Y  商户编号
		bizType  Y  固定值 TRANSACTION
		code  Y  【见返回码】
		message  N  描述信息
		status  Y  CONFIRM 或者 CANCEL
		requestNo  Y  请求流水号
	 */
	public BHACommonResponse completeTransaction(String platformNo,String requestNo, BHACompleteTransactionModeEnum modeEnum,String notifyUrl) throws ClientProtocolException, IOException{
		Assert.hasLength(platformNo, "平台编号不能为空");
		Assert.hasLength(requestNo, "流水号不能为空");
		Assert.hasLength(notifyUrl, "回调地址不能为空");

		BHACompleteTransactionRequest req = new BHACompleteTransactionRequest();
		req.setPlatformNo(platformNo);
		req.setRequestNo(requestNo);
		req.setMode(modeEnum);
		req.setNotifyUrl(notifyUrl);
		return BHAUtil.doBHAService(BHAServiceNameEnum.COMPLETE_TRANSACTION, BHACommonResponse.class, req);

	}
	
	/**
	 * 冻结资金
	 * service 名称  FREEZE
	 * --------------输入参数------------------
	 * platformNo  Y  商户编号
		platformUserNo  Y  平台会员编号
		requestNo  Y  请求流水号
		amount  Y  冻结金额
		expired  Y  到期自劢解冻
	 * ------------输出参数-------------------
	 * platformNo  Y  商户编号
		code  Y  【见返回码】
		description  N  描述信息
	 * -------------回调通知-------------------
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public BHACommonResponse freeze(String platformUserNo,String platformNo,BigDecimal amount,Date expired,String requestNo) throws ClientProtocolException, IOException{
		Assert.hasLength(platformNo, "平台编号不能为空");
		Assert.hasLength(platformUserNo, "平台用户编号不能为空");
		Assert.hasLength(requestNo, "流水号不能为空");
		BHAFreezeRequest freezeRequest = new BHAFreezeRequest();
		freezeRequest.setPlatformUserNo(platformUserNo);
		freezeRequest.setPlatformNo(platformNo);
		freezeRequest.setAmount(amount.toString());
		freezeRequest.setExpired(sdf.format(expired));
		freezeRequest.setRequestNo(requestNo);
		
		return BHAUtil.doBHAService(BHAServiceNameEnum.FREEZE, BHACommonResponse.class, freezeRequest);
		
	}
	
	/**
	 * 解冻资金
	 * service 名称  UNFREEZE 
	 * --------------输入参数------------------
	 * platformNo  Y  商户编号
		freezeRequestNo  Y  冻结时的请求流水号
	 * ------------输出参数-------------------
	 * platformNo  Y  商户编号
		code  Y  【见返回码】
		description  N  描述信息
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public BHACommonResponse unFreeze(String platformNo,String freezeRequestNo) throws ClientProtocolException, IOException{
		Assert.hasLength(platformNo, "平台编号不能为空");
		Assert.hasLength(freezeRequestNo, "流水号不能为空");
		
		BHAUnFreezeRequest freezeRequest = new BHAUnFreezeRequest();
		freezeRequest.setPlatformNo(platformNo);
		freezeRequest.setFreezeRequestNo(freezeRequestNo);
		
		return BHAUtil.doBHAService(BHAServiceNameEnum.UNFREEZE, BHACommonResponse.class, freezeRequest);
	}
	
	/**
	 * 平台信息
	 * service 名称  PLATFORM_INFO 
	 * --------------输入参数------------------
	 * platformNo  Y  商户编号
		notifyUrl  Y  异步通知地址(用亍接收银行验证卡片结果，即绑卡成功或失败状态，通知参数格式详见 2.4.3
		绑卡回调通知)
	 * ------------输出参数-------------------
	 * platformNo  Y  商户编号
		code  Y  【见返回码】
		description  Y  描述信息
		notifyUrl  Y  异步通知地址
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public BHACommonResponse platformInfo(String platformNo,String notifyUrl) throws ClientProtocolException, IOException{
		Assert.hasLength(platformNo, "平台编号不能为空");
		Assert.hasLength(notifyUrl, "回调地址不能为空");
		BHAPlatformInfoRequest req = new BHAPlatformInfoRequest();
		req.setPlatformNo(platformNo);
		req.setNotifyUrl(notifyUrl);
		return BHAUtil.doBHAService(BHAServiceNameEnum.PLATFORM_INFO, BHACommonResponse.class, req);
	}
	
	/**
	 * 标的查询 
	 * service 名称  PROJECT_QUERY 
	 * --------------输入参数------------------
	 * platformNo  Y  商户编号
		orderNo  Y  标的号
	 * ------------输出参数-------------------
	 * platformNo  Y  商户编号
		code  Y  【见返回码】
		description  Y  描述信息
		targetPlatformUserNo  Y  项目借款方平台用户编号
		targetUserType  Y  项目借款方用户类型
		transferAmount  Y  项目金额
		autoRepayment  Y  是否可以自劢还款
		createTime  Y  项目创建时间
		notifyUrl  Y  异步通知地址
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public BHAProjectQueryResponse projectQuery(String platformNo,String orderNo) throws ClientProtocolException, IOException{
		Assert.hasLength(platformNo, "平台编号不能为空");
		Assert.hasLength(orderNo, "标的号不能为空");
		BHAProjectQueryRequest req = new BHAProjectQueryRequest();
		req.setPlatformNo(platformNo);
		req.setOrderNo(orderNo);
		
		return BHAUtil.doBHAService(BHAServiceNameEnum.PROJECT_QUERY, BHAProjectQueryResponse.class, req);

	}
	
	/**
	 * 单业务查询
	 * service 名称  QUERY 
	 * --------------输入参数------------------
	 * platformNo  Y  商户编号
		requestNo  Y  各个业务的请求流水号
		mode  Y  查询模式，有如下枚丼值：
			WITHDRAW_RECORD：提现记录
			RECHARGE_RECORD：充值记录
			CP_TRANSACTION：转账记录
			FREEZERE_RECORD：冻结/解冻接口
	 * ------------输出参数-------------------
	 * 充值记录：
			参数名称  必填  参数说明
			amount  Y  充值金额
			userNo  Y  充值用户
			createTime  Y  充值时间
			status  Y  充值状态：
			INIT 未付,
			SUCCESS 付款成功
		提现记录：
			参数名称  必填  参数说明
			amount  Y  提现金额
			userNo  Y  提现用户
			createTime  Y  提现时间
			status  Y  提现状态：
			INIT,
			SUCCESS
			remitStatus  N  REMIT_SUCCESS 打款成功 REMIT_FAILURE 打款失败 REMITING 打款中
			转账记录：
				参数名称  必填  参数说明
				requestNo  Y  流水号
				bizType  Y  业务类型
				amount  Y  转账总金额
				status  Y  订单状态：PREAUTH 已授权。CONFIRM：已确讣出款。CANCEL：已取消。DIRECT：直接划转。
				subStatus  Y  处理状态 : PROCESSING：处理中。SUCCESS：成功。ERROR：异常。FAIL：失败
			冻结/解冻记录：
				参数名称  必填  参数说明
				requestNo  Y  流水号
				platformUserNo  Y  平台会员编号
				amount  Y  冻结金额
				expired  Y  过期时间
				createTime  Y  创建时间
				status  Y  处理状态:INIT，FREEZED，UNFREEZED
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public BHABaseResponse query(String platformNo,String requestNo,BHAQueryModeEnum modeE) throws ClientProtocolException, IOException{
		Assert.hasLength(platformNo, "平台编号不能为空");
		Assert.hasLength(requestNo, "流水号不能为空");
		BHABaseResponse res = null;
		BHAQueryRequest req = new BHAQueryRequest();
		req.setPlatformNo(platformNo);
		req.setRequestNo(requestNo);
		req.setMode(modeE);
		
		switch (modeE) {
		case RECHARGE_RECORD:
			res = BHAUtil.doBHAService(BHAServiceNameEnum.QUERY, BHARechargeRecordResponse.class, req);
			break;
		case WITHDRAW_RECORD:
			res = BHAUtil.doBHAService(BHAServiceNameEnum.QUERY, BHAWithdrawRecordResponse.class, req);
			break;
		case CP_TRANSACTION:
			res = BHAUtil.doBHAService(BHAServiceNameEnum.QUERY, BHACpTransactionRecordResponse.class, req);
			break;
		case FREEZERE_RECORD:
			res = BHAUtil.doBHAService(BHAServiceNameEnum.QUERY, BHAFreezeRecordResponse.class, req);
			break;
		default:
			break;
		}
		return res;
	}
	
	/**
	 * 取消自动投标授权
		service 名称  CANCEL_AUTHORIZE_AUTO_TRANSFER 
	 * --------------输入参数------------------
		参数名称  必填  参数说明
		platformNo  Y  商户编号
		platformUserNo  Y  平台会员编号
		requestNo  Y  请求流水号
	 * ------------输出参数-------------------
		参数名称  必填  参数说明
		platformNo  Y  商户编号
		code  Y  【见返回码】
		description  N  描述信息
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public BHACommonResponse cancelAuthorizeAutoTransfer(String platformNo,String requestNo,String platformUserNo) throws ClientProtocolException, IOException{
		Assert.hasLength(platformNo, "平台编号不能为空");
		Assert.hasLength(requestNo, "流水号不能为空");
		Assert.hasLength(platformUserNo, "平台用户编号不能为空");

		BHACancelAuthorizeAutoTransferRequest req = new BHACancelAuthorizeAutoTransferRequest();
		req.setPlatformNo(platformNo);
		req.setRequestNo(requestNo);
		req.setPlatformUserNo(platformUserNo);
		
		return BHAUtil.doBHAService(BHAServiceNameEnum.CANCEL_AUTHORIZE_AUTO_TRANSFER, BHACommonResponse.class, req);
	}
	
	/**
	 * 取消自动还款授权
	 * service 名称  CANCEL_AUTHORIZE_AUTO_REPAYMENT
	 * --------------输入参数------------------
	 * platformNo  Y  商户编号
		platformUserNo  Y  平台会员编号
		requestNo  Y  请求流水号
		orderNo  Y  标的号
	 * ------------输出参数-------------------
	 * platformNo  Y  商户编号
		code  Y  【见返回码】
		description  N  描述信息
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public BHACommonResponse cancelAuthorizeAutoRepayment(String platformNo,String requestNo,String platformUserNo,String orderNo) throws ClientProtocolException, IOException{
		Assert.hasLength(platformNo, "平台编号不能为空");
		Assert.hasLength(requestNo, "流水号不能为空");
		Assert.hasLength(platformUserNo, "平台用户编号不能为空");
		Assert.hasLength(orderNo, "标的号不能为空");

		BHACancelAuthorizeAutoRepaymentRequest req = new BHACancelAuthorizeAutoRepaymentRequest();
		req.setPlatformNo(platformNo);
		req.setRequestNo(requestNo);
		req.setPlatformUserNo(platformUserNo);
		req.setOrderNo(orderNo);
		return BHAUtil.doBHAService(BHAServiceNameEnum.CANCEL_AUTHORIZE_AUTO_REPAYMENT, BHACommonResponse.class, req);
	}
	
	/**
	 * obj转xml
	 * @param obj
	 * @return
	 */
	private String toXML(Object obj)  {
		StringWriter w = new StringWriter();
		JAXB.marshal(obj, w);
		return w.toString().replaceAll("[\\r\\n]", "");
	}
	
}
